package wviz.gui;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.Reader;
import java.text.NumberFormat;
import java.util.List;

import javax.swing.SwingWorker;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.NoLockFactory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.apache.tika.Tika;
import org.apache.tika.metadata.Metadata;

import prefuse.data.Graph;
import wviz.Constants;
import wviz.gui.graph.GraphGenerator;
import wviz.index.Cooc;
import wviz.index.StemAnalyzer;
import wviz.index.TfCalculator;

/**
 * A background task which will read content and generate graph. When task is
 * done, it will update the visualisation panel by calling related methods in
 * parent application.
 */
public class VisualisationTask extends SwingWorker<Graph, Void> {

	protected InputStream inStream;
	protected String pastedString;
	protected String twitterQuery;

	protected final int maxTermsToAnalyze;
	protected final int graphLinks;
	protected static IndexReader ir;

	/**
	 * Time taken to generate visualisation graph in miliseconds.
	 */
	protected long elapsedTime;
	protected T2vPanel parent;
	protected boolean adjustment = false;
	protected String filename = null;
	

	public VisualisationTask(T2vPanel parent, InputStream str,
			int numberTermsToAnalyze, int links, String fname) {		
		
		this.parent = parent;
		this.inStream = str;
		this.maxTermsToAnalyze = numberTermsToAnalyze;
		this.graphLinks = links;
		adjustment = false;
		filename = fname;	
	}

	public VisualisationTask(T2vPanel parent, int numberTermsToAnalyze,
			int graphLinks) {
		this.parent = parent;
		this.maxTermsToAnalyze = numberTermsToAnalyze;
		this.graphLinks = graphLinks;
		adjustment = true;
	}

	public VisualisationTask(T2vPanel parent2, String s,
			int numberTermsToAnalyze, int graphLinks2) {
		this.parent = parent2;
		this.pastedString = s;
		this.maxTermsToAnalyze = numberTermsToAnalyze;
		this.graphLinks = graphLinks2;
		adjustment = false;

	}

	
	/**
	 * Background task to be run in a separate thread by SwingWorker; in this
	 * case cration of a g in a separate thread in background
	 * 
	 * @return generated graph
	 * @throws Exception
	 *             if any io exception occurs during reading content of the file
	 */
	protected Graph doInBackground() throws Exception {

		final long startTime = System.nanoTime();
		BufferedReader inb = null;
		System.out.println("in doinbackgroud");
		Analyzer analyzer = new StemAnalyzer();

		IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_35,
				analyzer);

		Document doc = new Document();
		List<String[]> pairs = null;


		if (!adjustment || ir == null) {
			RAMDirectory ramDir = new RAMDirectory();
			ramDir.setLockFactory(NoLockFactory.getNoLockFactory());

			IndexWriter writer = new IndexWriter(ramDir, config);

			Tika tika = new Tika();
			// tika.setMaxStringLength(-1);

			Reader in;	

			if (filename != null) {

				// MediaType mediaType;
				Metadata md = new Metadata();
				md.set(Metadata.RESOURCE_NAME_KEY, filename);

				 in = tika.parse(inStream, md);		
			} else {
				 in = tika.parse(inStream);				
			}

			inb = new BufferedReader(in);

			doc.add(new Field(Constants.FIELD_CONTENTS, inb,
					Field.TermVector.WITH_POSITIONS));
			writer.addDocument(doc);
			inb.close();

			writer.close();
			ir = IndexReader.open(ramDir, true);
		}

		TfCalculator tf = new TfCalculator(ir, maxTermsToAnalyze);

		Term[] highFreqTerms = tf.calcTfIdfSortedSet();

		for (int i = 0; i < highFreqTerms.length && i < 20; i++) {
			System.out.println(" in Viz task term: " + highFreqTerms[i]
					+ " number " + i);
		}
		Cooc cooc = new Cooc(highFreqTerms, ir, this.graphLinks);
		pairs = cooc.getWordPairsForGraph();
		Graph graph = GraphGenerator.pairListToGraph(pairs);
		elapsedTime = (System.nanoTime() - startTime) / 1000000L;

		return graph;
	}

	@Override
	protected void done() {
		if (isCancelled()) {
			parent.setStatusMessageText("");
			return;
		}

		try {
			// getting the generated graph
			Graph g = get();
			parent.setStatusMessageText(String.format(
					"Visualisation took %s miliseconds| ", NumberFormat
							.getInstance().format(elapsedTime)));
			parent.visualisationTaskFinished(g);
		} catch (Exception e) {
			parent.visualisationTaskFailed(e);
		}
	}
}